home *** CD-ROM | disk | FTP | other *** search
- /*==============================================================================
- Project: POV-Ray
-
- Version: 3
-
- File: TextEditor.c
-
- Description:
- This file contains Macintosh-specific routines for the
- source code text editor.
- ------------------------------------------------------------------------------
- Author:
- Symantec, mods by Jim Nitchals, more mods & Think 6 updates by Eduard [esp] Schwan
- ------------------------------------------------------------------------------
- from Persistence of Vision(tm) Ray Tracer
- Copyright 1996 Persistence of Vision Team
- ------------------------------------------------------------------------------
- NOTICE: This source code file is provided so that users may experiment
- with enhancements to POV-Ray and to port the software to platforms other
- than those supported by the POV-Ray Team. There are strict rules under
- which you are permitted to use this file. The rules are in the file
- named POVLEGAL.DOC which should be distributed with this file. If
- POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- Forum. The latest version of POV-Ray may be found there as well.
-
- This program is based on the popular DKB raytracer version 2.12.
- DKBTrace was originally written by David K. Buck.
- DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- ------------------------------------------------------------------------------
- Change History:
- 920815 [jln] version 1.0 Mac released.
- 920908 [esp] version 1.1 alpha Mac
- 920912 [esp] changed window id to 1000 & moved #define here from POVMac.h
- 921110 [esp] Added TextEditor.h file & pulled in defs to there
- 921207 [esp] Added code to handle zoom box
- 921211 [esp] Fixed bug in Open: if open failed, left New & Open items dimmed
- 930710 [esp] fixed "cancelling of save-as dialog" logic
- 930817 [esp] Added FlushVol calls in SaveFile and SaveAs to force disk update
- 931001 [esp] version 2.0 finished (Released on 10/4/93)
- 931119 [djh] 2.0.1 conditionally compiles for PPC machines, keyword __powerc
- 940416 [PFS] 2.2.1 greatly reworked to clean up PPC support and provide CodeWarrior projects
- 960422 [esp] 3.0b6 Major rework to use TE32K code for >32K text files
- 960620 [esp] 3.0b7 Added code to convert Unix LF-only files to Mac CR-only files.
- 960621 [esp] 3.0b7 Added simple Match Brace function.
- 960714 [esp] 3.0F1 Added real Revert dialog instead of reusing save dialog!
- ==============================================================================*/
-
-
- #include "TextEditor.h"
-
- /*==== Standard C headers ====*/
- #include <stdio.h>
-
- /*==== Mac toolbox headers ====*/
-
- #include <types.h> // basic types
- #include <errors.h> // noErr, etc.
- #include <files.h> // FSOpen, etc.
- #include <fonts.h> // monaco, etc.
- #include <memory.h> // NewHandle, etc.
- #include <menus.h> // MenuHandle, etc.
- #include <packages.h> // SFGetFile, etc.
- #include <scrap.h> // ZeroScrap, etc.
- #include <toolutils.h> // watchCursor, etc.
- #include <windows.h> // SizeWindow, etc.
- #include <processes.h> // ExitToShell
-
-
- /*==== POV Mac Library routines =====*/
-
- #include "PovMac.h" // fmn_open
- #include "UtilLib.h"
- #include "ImageWindow.h" // CloseImageWindow(), gImageWindIsValid
- #include "FilePrefs.h"
- #include "TE32K.h" // TE32K support
- #include "UndoRedoSystem.h"
-
- /*==== globals (external scope) ====*/
-
- WindowPtr gSrcWind_Window;
- Boolean gSrcWind_dirty;
- Boolean gSrcWind_visible;
- Str255 gSrcWind_FileName;
- short gSrcWind_VRefNum;
- TE32KHandle gSrcWind_TE32KH;
-
-
- /*==== globals (local scope) ====*/
-
- static WindowRecord gWindowRecord;
- static int gLineCount;
- static Cursor gEditCursor;
- static ControlActionUPP vScrollUPP = NULL;
- static ControlHandle gSrcWind_VScroll;
-
- // this should be moved to a user preference when I have time!
- #define TAB_WIDTH 4
- #define EDITOR_TEXTFONT monaco
- #define EDITOR_TEXTSIZE 9
-
-
- // ==============================================
- static pascal void ScrollProc(ControlHandle theControl, short theCode);
- static void SrcWindClickLoop(void);
- static void SrcWindClickRoutine(void);
-
- // ==============================================
- #define SrcWind_WindID 1000
- #define ErrorAlert 256
- #define SaveAlertID 257
- #define RevertAlertID 258
-
- #define aaSave 1
- #define aaDiscard 2
- #define aaCancel 3
-
- #define SBarWidth 15
-
- #define ours(w) ((gSrcWind_Window != NULL) && (w == gSrcWind_Window))
-
- #define kUntitledFName "\pUntitled.POV"
-
-
- // ==============================================
- int SetUpFiles(void)
- {
- pStrCopy(kUntitledFName, gSrcWind_FileName);
- gSrcWind_VRefNum = 0;
- gSrcWind_dirty = 0;
- return 0; // should be void fn!?
- }
-
-
-
- // ==============================================
- int DoFile(int item)
- {
- short vRef, refNum;
- Str255 fn;
-
- switch (item) {
-
- case fmn_open:
- HideWindow(gSrcWind_Window); /* gives a sense of closing the old file. */
- if (OldFile(fn, &vRef))
- {
- gSrcWind_VRefNum = 0;
- gSrcWind_dirty = false; // may turn ON in ReadFile
- if (FSOpen(fn, vRef, &refNum)==noErr) {
- if (ReadFile(refNum)==noErr) {
- pStrCopy(fn, gSrcWind_FileName);
- gSrcWind_VRefNum = vRef;
- SetWTitle(gSrcWind_Window, gSrcWind_FileName);
- }
- if (FSClose(refNum)==noErr) ;
- ShowWindow(gSrcWind_Window);
- gSrcWind_visible = true;
- TE32KSetSelect(0, 0, gSrcWind_TE32KH);
- ShowSelect();
-
- Init_UndoRedoSystem();
- }
- else
- FileError("\pError opening ", fn);
- }
- break;
-
- case fmn_close:
- if (gSrcWind_dirty)
- {
- int notClosed=0;
- ParamText("\pSave changes to \"", gSrcWind_FileName, "\p\"?", "\p");
- ShowArrowCursor();
- switch (Alert(SaveAlertID, 0L))
- {
- case aaSave:
- if (gSrcWind_VRefNum == 0)
- { // create new file
- pStrCopy(gSrcWind_FileName, fn);
- if (!SaveAs(fn, &vRef))
- notClosed=1;
- }
- else // save existing file
- if (!SaveFile(gSrcWind_FileName, gSrcWind_VRefNum))
- notClosed=1;
- break;
- case aaCancel:
- notClosed=1;
- break;
- case aaDiscard:
- gSrcWind_dirty = 0;
- break;
- }
- if (notClosed)
- return 0; // error, just return
- } // if dirty
-
- Dispose_UndoRedoSystem();
-
- CloseMyWindow();
- break;
-
- case fmn_save:
- // if file already open
- if (gSrcWind_VRefNum != 0)
- {
- if (!SaveFile(gSrcWind_FileName, gSrcWind_VRefNum))
- return(0);
- break;
- }
- // else drop through to here..
-
- case fmn_saveas:
- pStrCopy(gSrcWind_FileName, fn);
- if (SaveAs(fn, &vRef))
- {
- pStrCopy(fn, gSrcWind_FileName);
- gSrcWind_VRefNum = vRef;
- SetWTitle(gSrcWind_Window, gSrcWind_FileName);
- }
- else
- return(0);
- break;
-
- case fmn_revert:
- ParamText("\pRevert to last saved version of \"", gSrcWind_FileName, "\p\"?", "\p");
- ShowArrowCursor();
- switch (Alert(RevertAlertID, 0L)) {
- case aaSave:
- // delete existing text
- SelectAllText();
- SrcWindClearSel();
- // read file back in
- if ((gSrcWind_VRefNum != 0) &&
- (FSOpen(gSrcWind_FileName, gSrcWind_VRefNum, &refNum)==noErr))
- {
- gSrcWind_dirty = false; // may turn ON in ReadFile
- ReadFile(refNum);
- if (FSClose(refNum)==noErr) ;
- }
- ShowWindow(gSrcWind_Window);
- gSrcWind_visible = true;
- UpdateWindow(gSrcWind_Window);
- case aaCancel:
- case aaDiscard:
- return(0);
- }
-
- break;
-
- case fmn_quit:
- Dispose_UndoRedoSystem();
- if (DoFile(fmn_close))
- ExitToShell();
- }
- return(1);
- }
-
-
-
- // ==============================================
- static Point SFwhere;
- static SFReply reply;
-
-
- int SaveAs(Str255 fn, short *vRef)
- {
- short refNum;
-
- if (NewFile(fn, vRef))
- if (!CreateFile(fn, vRef, &refNum))
- {
- FileError("\pError creating file ", fn);
- return (0);
- }
- else
- {
- char hstate;
-
- hstate = HGetState((**gSrcWind_TE32KH).hText);
- HLock((**gSrcWind_TE32KH).hText);
- if (WriteFile(refNum, (*(**gSrcWind_TE32KH).hText), (long)(**gSrcWind_TE32KH).teLength))
- {
- FileError("\pError writing file ", fn);
- return (0);
- }
- HSetState((**gSrcWind_TE32KH).hText, hstate);
- FSClose(refNum);
- gSrcWind_dirty = 0;
- // flush any buffers to disk
- FlushVol(NULL, *vRef);
- return(1);
- }
- return (0);
- }
-
-
-
- // ==============================================
- int SaveFile(Str255 fn, short vRef)
- {
- short refNum;
- short anError;
-
- anError = FSOpen(fn, vRef, &refNum);
- if (anError != noErr)
- {
- FileError("\pError opening file ", fn);
- return (1);
- }
- else
- {
- char hstate;
-
- hstate = HGetState((**gSrcWind_TE32KH).hText);
- HLock((**gSrcWind_TE32KH).hText);
- anError = WriteFile(refNum, (*(**gSrcWind_TE32KH).hText), (long)(**gSrcWind_TE32KH).teLength);
- if (anError)
- FileError("\pError writing file ", fn);
- HSetState((**gSrcWind_TE32KH).hText, hstate);
- gSrcWind_dirty = 0;
- FSClose(refNum);
- // save prefs out too
- FilePrefs_Write(vRef, fn);
- // flush any buffers to disk
- FlushVol(NULL, vRef);
- return(1);
- }
- }
-
-
-
- // ==============================================
- int NewFile(Str255 fn, short *vRef)
- {
- ShowArrowCursor();
- GetBestDialogPos(&SFwhere, (WindowPtr)&gp2wWindow);
- SFPutFile(SFwhere, "\pSave POV-Ray text file as", fn, 0L, &reply);
- if (!reply.good)
- return (0);
- else {
- pStrCopy(reply.fName, fn);
- *vRef = reply.vRefNum;
- return(1);
- }
- }
-
-
-
- // ==============================================
- int OldFile(Str255 fn, short *vRef)
- {
- SFTypeList myTypes;
-
- myTypes[0]='TEXT';
-
- ShowArrowCursor();
- GetBestDialogPos(&SFwhere, (WindowPtr)&gp2wWindow);
- SFGetFile(SFwhere, "\p", 0L, 1, myTypes, 0L, &reply );
-
- if (!reply.good)
- return (0);
- else {
- pStrCopy(reply.fName, fn);
- *vRef = reply.vRefNum;
- return(1);
- }
- }
-
-
-
- // ==============================================
- int CreateFile(Str255 fn, short *vRef, short *theRef)
- {
- OSErr io;
-
- io=Create(fn, *vRef, kAppSignature, 'TEXT');
- if ((io == noErr) || (io == dupFNErr))
- io = FSOpen(fn, *vRef, theRef );
-
- return ((io == noErr) || (io == dupFNErr));
- }
-
-
-
- // ==============================================
- int WriteFile(short refNum, char *p, long num)
- {
- OSErr io;
- /* gee, somebody should check the return code for errors */
- io=FSWrite(refNum, &num, p);
- if (io)
- return(io);
- io=SetEOF(refNum, num);
- return(io);
- }
-
-
-
- // ==============================================
- // This routine sweeps through the buffer passed, looking for lone LFs
- // (with no CR before them ala MSDOS) and switches the LF in place
- // to a CR for the Macintosh. This allows us to read/convert Unix
- // scene files and convert them right to Mac format.
- // SIDE EFFECT: Turns on the global DIRTY flag if any LFs are converted,
- // forcing user to save the altered file or abort the changes.
- #define LF_CHAR 0x0a
- #define CR_CHAR 0x0d
- static void ConvertUnixBuffer(Boolean * sawCRFlag, char * buffer, long bufferSize)
- {
- // loop through entire buffer...
- for ( ; bufferSize; bufferSize--, buffer++)
- {
- // Did we find a line feed?
- if (*buffer == LF_CHAR)
- {
- // if previous char was NOT a CR, it is OK to convert
- if (*sawCRFlag == false)
- {
- *buffer = CR_CHAR; // convert from Unix LF to Mac CR
- gSrcWind_dirty = true; // mark ourselves as dirty!
- }
- *sawCRFlag = false; // nope, it was a line feed!
- }
- // is it a CR?
- else if (*buffer == CR_CHAR)
- {
- *sawCRFlag = false; // Oh oh, remember that we saw this for next time through!
- }
- // it is some other uninteresting character...
- else
- *sawCRFlag = false; // nope, it was something else!
- }
- }
-
- // ==============================================
- #define READ_BUF_SIZE 1024L*10L // how many KBytes to read at a time from file
- int ReadFile(short refNum)
- {
- OSErr io = noErr;
- long totalBytes, count;
- Ptr buffer;
- Boolean crFlag=false;
-
- // allocate temp buffer to read into
- buffer = NewPtr(READ_BUF_SIZE);
- if (buffer == NULL)
- return -108; // out of mem
-
- // get rid of any previous TE stuff
- (**gSrcWind_TE32KH).selStart = 0;
- (**gSrcWind_TE32KH).selEnd = (**gSrcWind_TE32KH).teLength;
- TE32KDelete(gSrcWind_TE32KH);
- // how many total bytes in file?
- GetEOF(refNum, &totalBytes);
- // will we run out of memory?
- if (totalBytes > FreeMem()*2L)
- return -108; // out of mem
- // read the file, "READ_BUF_SIZE" bytes at a time
- do {
- // how much to read this pass?
- count = (totalBytes >= READ_BUF_SIZE) ? READ_BUF_SIZE : totalBytes;
- // read it
- if (count > 0L)
- io = FSRead(refNum, &count, buffer);
- // Convert the buffer from Unix if need be
- ConvertUnixBuffer(&crFlag, buffer, count);
- // stick chars into TE buffer
- if (count > 0L)
- TE32KInsert(buffer, count, gSrcWind_TE32KH);
- // calculate how much is left to read
- totalBytes -= count;
- } while ((io==noErr) && (totalBytes > 0L));
- // done with temp buffer
- DisposePtr(buffer);
-
- return (io);
- }
-
-
-
- // ==============================================
- /* copies a pascal string from p1 to p2 */
- int pStrCopy(StringPtr p1, StringPtr p2)
- {
- register int len = *p1;
-
- *(p2++) = *(p1++);
- while (--len>=0)
- *(p2++)=*(p1++);
- return 0; // should be void fn!?
- }
-
-
-
- // ==============================================
- int FileError(Str255 s, Str255 f)
- {
- ParamText(s, f,"\p", "\p");
- Alert(ErrorAlert, 0L);
- return 0; // should be void fn!?
- }
-
-
-
- // ==============================================
- void PreInitWindows(void)
- {
- if (gSrcWind_Window == 0)
- {
- SetUpWindows();
- HideWindow(gSrcWind_Window); /* just in case it's already visible */
- }
- }
-
-
- // ==============================================
- int SetUpWindows(void)
- {
- Rect viewRect;
- Rect vScrollRect;
- LongRect LviewRect;
-
- gSrcWind_Window = GetNewWindow(SrcWind_WindID, &gWindowRecord, (WindowPtr)NULL);
- if (!gSrcWind_Window)
- return 1;
-
- // set the editor's font & size
- SetPort(gSrcWind_Window);
- TextFont(EDITOR_TEXTFONT);
- TextSize(EDITOR_TEXTSIZE);
-
- vScrollRect = (*gSrcWind_Window).portRect;
- vScrollRect.left = vScrollRect.right-SBarWidth;
- vScrollRect.right += 1;
- vScrollRect.bottom -= SBarWidth-1;
- vScrollRect.top -= 1;
- gSrcWind_VScroll = NewControl( gSrcWind_Window, &vScrollRect,
- "\pSrcVScroll", 1, 0, 0, 0, scrollBarProc, 0L);
-
- viewRect = qd.thePort->portRect;
- viewRect.right -= SBarWidth;
- viewRect.bottom -= SBarWidth;
- InsetRect(&viewRect, 2, 2);
- RectToLongRect(&viewRect, &LviewRect);
- gSrcWind_TE32KH = TE32KNew(&LviewRect, &LviewRect);
- if (gSrcWind_TE32KH)
- {
- // Set up the tab width
- (**gSrcWind_TE32KH).tabChars = TAB_WIDTH;
- TE32KSetFontStuff(EDITOR_TEXTFONT, 0, 0, EDITOR_TEXTSIZE, gSrcWind_TE32KH);
-
- TE32KDeactivate(gSrcWind_TE32KH);
- // turn on autoscrolling
- // Not this way...
- // (void)TE32KFeatureFlag(teFAutoScr, teBitSet, gSrcWind_TE32KH);
- // TE32KAutoView(TRUE, gSrcWind_TE32KH);
- // this way!
- (**gSrcWind_TE32KH).clikLoop = (TE32KProcPtr) SrcWindClickLoop;
-
- // turn on outline hilighting (not working??? [esp])
- (void)TE32KFeatureFlag(teFOutlineHilite, teBitSet, gSrcWind_TE32KH);
- }
- SetView((WindowPtr) qd.thePort);
-
- if (gSrcWind_VScroll)
- HideControl(gSrcWind_VScroll);
-
- gSrcWind_dirty = 0;
-
- Init_UndoRedoSystem();
-
- return 0; // should be void fn!?
- }
-
-
- // ==============================================
- /*
- From the TE32K readme:
- Warning #2: since TE32K supports editing of such large text files, the text rectangle (destRect)
- can easily by taller than 32767 pixels. “So what?” you ask? Well, this means that you had
- better not be using the value ((**theTEH32K).viewRect.top - (**theTEH32K).destRect.top)
- for the setting in your vertical scroll control. If you do, then you will likely end up setting
- the control value to something much larger than its maximum of 32767. Instead, you would be wise
- to set the control's value to
- ((**theTEH32K).viewRect.top - (**theTEH32K).destRect.top) / (**theTEH32K).lineHeight,
- which means that now your control keeps track of the top line number, rather than the pixel
- distance between the top of the destRect and viewRect.
- */
- static int AdjustScrollBar(void)
- {
- short ctlVal,screenLines,numLines,oldVal;
-
- ctlVal = ((**gSrcWind_TE32KH).viewRect.top - (**gSrcWind_TE32KH).destRect.top)/(**gSrcWind_TE32KH).lineHeight;
- screenLines = ((**gSrcWind_TE32KH).viewRect.bottom - (**gSrcWind_TE32KH).viewRect.top)/(**gSrcWind_TE32KH).lineHeight;
- numLines = (**gSrcWind_TE32KH).nLines;
-
- if (ctlVal > numLines-screenLines)
- SetControlMaximum(gSrcWind_VScroll, ctlVal);
- else
- SetControlMaximum(gSrcWind_VScroll, (numLines-screenLines > 0) ? numLines-screenLines : 0);
-
- oldVal = GetControlValue(gSrcWind_VScroll);
-
- if (oldVal != ctlVal)
- SetControlValue(gSrcWind_VScroll, ctlVal);
-
- // ShowControl(gSrcWind_VScroll);
- return 0; // should be void fn!?
- }
-
-
-
- // ==============================================
- int ShowSelect(void)
- {
- int topLine, bottomLine, theLine, scrollAmt;
-
- AdjustScrollBar();
-
- // what lines are shown...
- topLine = GetControlValue(gSrcWind_VScroll);
- bottomLine = topLine + gLineCount;
- // if selection is off the screen...
- if ((**gSrcWind_TE32KH).selStart < (**gSrcWind_TE32KH).lineStarts[topLine] ||
- (**gSrcWind_TE32KH).selStart >= (**gSrcWind_TE32KH).lineStarts[bottomLine])
- {
- // count up the lines to current
- for ( theLine = 0;
- (**gSrcWind_TE32KH).selStart >= (**gSrcWind_TE32KH).lineStarts[theLine];
- theLine++)
- ;
- // position back 1/2 screen so selection is in middle of screen
- theLine = theLine - gLineCount / 2;
- if (theLine<0)
- theLine=0;
- SetControlValue(gSrcWind_VScroll, theLine);
- scrollAmt = topLine-theLine;
- TE32KScroll(0L, (long)((long)scrollAmt*(long)(**gSrcWind_TE32KH).lineHeight), gSrcWind_TE32KH);
- AdjustScrollBar();
- }
- return 0; // should be void fn!?
- }
-
-
-
- // ==============================================
- void SelectAllText(void)
- {
- End_Make_Undoable();
- End_Make_Redoable();
- TE32KSetSelect(0, (**gSrcWind_TE32KH).teLength, gSrcWind_TE32KH);
- UpdateWindow(gSrcWind_Window);
- }
-
-
-
- // ==============================================
- int SetView(WindowPtr w)
- {
- Rect TviewRect;
- // calculate viewable area
- TviewRect = w->portRect;
- TviewRect.right -= SBarWidth;
- TviewRect.bottom -= SBarWidth;
- InsetRect(&TviewRect, 2, 2); // add 2 pixel padding inside window frame
- RectToLongRect(&TviewRect, &(**gSrcWind_TE32KH).viewRect);
-
- gLineCount = ((**gSrcWind_TE32KH).viewRect.bottom-(**gSrcWind_TE32KH).viewRect.top)/(**gSrcWind_TE32KH).lineHeight;
- (**gSrcWind_TE32KH).viewRect.bottom = (**gSrcWind_TE32KH).viewRect.top + (**gSrcWind_TE32KH).lineHeight*gLineCount;
- (**gSrcWind_TE32KH).destRect.right = (**gSrcWind_TE32KH).viewRect.right;
- TE32KCalText(gSrcWind_TE32KH);
- return 0; // should be void fn!?
- }
-
-
-
- // ==============================================
- int UpdateWindow(WindowPtr theWindow)
- {
- GrafPtr savePort;
- LongRect LviewRect;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- BeginUpdate(theWindow);
- EraseRect(&theWindow->portRect);
- DrawControls(theWindow);
- DrawGrowIcon(theWindow);
- RectToLongRect(&theWindow->portRect, &LviewRect);
- TE32KUpdate(&LviewRect, gSrcWind_TE32KH);
- EndUpdate(theWindow);
-
- SetPort(savePort);
- return 0; // should be void fn!?
- }
-
-
- // ==============================================
- // So outside can call scrolling without accessing locals
- void ScrollEditHome(void)
- {
- short controlMin,controlVal;
- int scrollAmt;
-
- controlMin = GetControlMinimum(gSrcWind_VScroll);
- controlVal = GetControlValue(gSrcWind_VScroll);
-
- // how far to get back to top?
- scrollAmt = controlVal-controlMin;
- if (scrollAmt>0)
- {
- // set scrollbar to min
- SetControlValue(gSrcWind_VScroll, controlMin);
- TE32KScroll(0L, (long)((long)scrollAmt*(long)(**gSrcWind_TE32KH).lineHeight), gSrcWind_TE32KH);
- AdjustScrollBar();
- }
- }
-
- // ==============================================
- // So outside can call scrolling without accessing locals
- void ScrollEditEnd(void)
- {
- short controlMax,controlVal;
- int scrollAmt;
-
- controlMax = GetControlMaximum(gSrcWind_VScroll);
- controlVal = GetControlValue(gSrcWind_VScroll);
-
- scrollAmt = controlMax-controlVal;
- if (scrollAmt>0)
- {
- SetControlValue(gSrcWind_VScroll, controlMax);
- TE32KScroll(0L, (long)((long)-scrollAmt*(long)(**gSrcWind_TE32KH).lineHeight), gSrcWind_TE32KH);
- AdjustScrollBar();
- }
- }
-
- // ==============================================
- // So outside can call scrolling without accessing locals
- void ScrollEditPage(short thePartCode)
- {
- ScrollProc(gSrcWind_VScroll, thePartCode);
- }
-
-
- // ==============================================
- static pascal void ScrollProc(ControlHandle theControl, short theCode)
- {
- short controlMax,controlMin,controlVal;
- long lines;
- int scrollAmt;
-
- if (theCode == 0)
- return ;
-
- controlMax = GetControlMaximum(theControl);
- controlMin = GetControlMinimum(theControl);
- controlVal = GetControlValue(theControl);
-
- switch (theCode) {
- case kControlUpButtonPart:
- if (controlVal > controlMin)
- {
- SetControlValue(theControl, controlVal-1);
- TE32KScroll(0L, (long)(**gSrcWind_TE32KH).lineHeight, gSrcWind_TE32KH);
- }
- break;
- case kControlDownButtonPart:
- if (controlVal < controlMax)
- {
- SetControlValue(theControl, controlVal+1);
- TE32KScroll(0L, (long)-(**gSrcWind_TE32KH).lineHeight, gSrcWind_TE32KH);
- }
- break;
- case kControlPageUpPart:
- if (controlVal > controlMin)
- {
- // calculate # of lines in a page (minus one) so we can scroll that far
- lines = ((*gSrcWind_TE32KH)->viewRect.bottom - (*gSrcWind_TE32KH)->viewRect.top)/(**gSrcWind_TE32KH).lineHeight-1;
- scrollAmt = (controlVal-lines < controlMin) ? controlVal-controlMin : lines;
- SetControlValue(theControl,controlVal-scrollAmt);
- TE32KScroll(0L,(long) ((long)scrollAmt*(long)(**gSrcWind_TE32KH).lineHeight), gSrcWind_TE32KH);
- }
- break;
- case kControlPageDownPart:
- if (controlVal < controlMax)
- {
- // calculate # of lines in a page (minus one) so we can scroll that far
- lines = ((**gSrcWind_TE32KH).viewRect.bottom - (**gSrcWind_TE32KH).viewRect.top)/(**gSrcWind_TE32KH).lineHeight-1;
- scrollAmt = (controlVal+lines > controlMax) ? controlMax-controlVal : lines;
- SetControlValue(theControl,controlVal+scrollAmt);
- TE32KScroll(0L, (long)((long)-scrollAmt*(long)(**gSrcWind_TE32KH).lineHeight), gSrcWind_TE32KH);
- }
- break;
- }
-
- AdjustScrollBar();
- }
-
-
-
- // ==============================================
- int DoContent(WindowPtr theWindow, EventRecord *theEvent)
- {
- short cntlCode;
- ControlHandle theControl;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- GlobalToLocal(&theEvent->where);
- if ((cntlCode = FindControl(theEvent->where, theWindow, &theControl)) == 0)
- {
- // Just a click in text area
- Rect shortRect;
- LongRect aLongRect;
- aLongRect = (**gSrcWind_TE32KH).viewRect;
- LongRectToRect(&aLongRect,&shortRect);
-
- if (PtInRect(theEvent->where, &shortRect))
- {
- End_Make_Undoable();
- End_Make_Redoable();
-
- TE32KClick(theEvent->where, (theEvent->modifiers & shiftKey)!=0, gSrcWind_TE32KH);
- }
- }
- else if(cntlCode == kControlIndicatorPart) // was old name: "inThumb"
- {
- // click/drag on the scrollbar thumb
- short oldVal = GetControlValue(theControl);
- TrackControl(theControl,theEvent->where, 0L);
- TE32KScroll(0L,
- (long)((oldVal - (long)GetControlValue(theControl)) * (long)(**gSrcWind_TE32KH).lineHeight),
- gSrcWind_TE32KH);
- }
- else
- {
- // click on other parts of scrollbar
- TrackControl(theControl, theEvent->where, vScrollUPP);
- }
-
- SetPort(savePort);
- return 0; // should be void fn!?
- }
-
- // ==============================================
- // Return selection of TE text in window
- long GetSrcWindselStart(void)
- {
- return (gSrcWind_TE32KH) ? (**gSrcWind_TE32KH).selStart : 0L;
- }
-
- // ==============================================
- // Return selection of TE text in window
- long GetSrcWindselEnd(void)
- {
- return (gSrcWind_TE32KH) ? (**gSrcWind_TE32KH).selEnd : 0L;
- }
-
- // ==============================================
- // Return size of TE text in window
- long GetSrcWindteLength(void)
- {
- return (gSrcWind_TE32KH) ? (**gSrcWind_TE32KH).teLength : 0L;
- }
-
- // ==============================================
- // Return handle to text in window
- Handle GetSrcWindhText(void)
- {
- return (gSrcWind_TE32KH) ? (**gSrcWind_TE32KH).hText : NULL;
- }
-
- // ==============================================
- // Cut the selection to the clipboard
- void SrcWindCutSelToClipboard(void)
- {
- Begin_Make_Undoable("Cutting",false);
- ZeroScrap(); // clear out the clipboard
- TE32KCut(gSrcWind_TE32KH);
- TE32KToScrap(); // export
- ShowSelect(); // scroll to cut area
- End_Make_Undoable();
- }
-
- // ==============================================
- // Copy the selection to the clipboard
- void SrcWindCopySelToClipboard(void)
- {
- Begin_Make_Undoable("Copying",false);
- ZeroScrap(); // clear out the clipboard
- TE32KCopy(gSrcWind_TE32KH);
- TE32KToScrap(); // export
- End_Make_Undoable();
- }
-
- // ==============================================
- // Paste from the clipboard
- void SrcWindPasteFromClipboard(void)
- {
- Begin_Make_Undoable("Pasting",false);
- TE32KFromScrap(); // import
- TE32KPaste(gSrcWind_TE32KH);
- ShowSelect(); // scroll to pasted area
- End_Make_Undoable();
- }
-
- // ==============================================
- void SrcWindClearSel(void)
- {
- Begin_Make_Undoable("Clearing",false);
- // delete it
- TE32KDelete(gSrcWind_TE32KH);
- End_Make_Undoable();
- }
-
- // ==============================================
- void SrcWindSetSelect(long selStart, long selEnd)
- {
- TE32KSetSelect(selStart, selEnd, gSrcWind_TE32KH);
- }
-
- // ==============================================
- void SrcWindDeleteAllText(void)
- {
- // select everything
- SrcWindSetSelect(0, -1);
- // delete it
- SrcWindClearSel();
- }
-
- // ==============================================
- void SrcWindTEKey(char theKey)
- {
- Begin_Make_Undoable("Typing",true);
- TE32KKey(theKey, gSrcWind_TE32KH);
- End_Make_Undoable();
- }
-
- // ==============================================
- void SrcWindTEDeleteLeftCharKey(void)
- {
- SrcWindSetSelect(GetSrcWindselStart() - 1, GetSrcWindselStart());
- Begin_Make_Undoable("Backspaces",true);
- TE32KDelete(gSrcWind_TE32KH);
- End_Make_Undoable();
- }
-
- // ==============================================
- void SrcWindTEDeleteRightCharKey(void)
- {
- SrcWindSetSelect(GetSrcWindselStart(), GetSrcWindselStart() + 1);
- Begin_Make_Undoable("Deletes",true);
- TE32KDelete(gSrcWind_TE32KH);
- End_Make_Undoable();
- }
-
- // ==============================================
- // Insert a chunk of text into the current selection in source window
- void DoSrcWindTextInsert(char * someTextPtr, long someTextSize)
- {
- Begin_Make_Undoable("Inserting",false);
- // Delete any selected text before the insertion
- TE32KDelete(gSrcWind_TE32KH);
- // stick in the text
- TE32KInsert(someTextPtr, someTextSize, gSrcWind_TE32KH);
- End_Make_Undoable();
- }
-
- // ==============================================
- // Move the source window's selection to the line # passed
- void GotoSrcWindLine(short line_to_go)
- {
- short i;
- long line_counter = 1,
- mySelStart = -1,
- mySelEnd = -1;
- Boolean foundStart = false;
- long theMaxLength;
- char *myptr;
-
- End_Make_Undoable();
- End_Make_Redoable();
-
- /* (Line 1 is a special case, of course!) */
- if (line_to_go <= 1)
- {
- mySelStart = 0;
- foundStart = true;
- }
-
- /* Find start and end of line */
- theMaxLength = (**gSrcWind_TE32KH).teLength-1;
- myptr = *(**gSrcWind_TE32KH).hText;
- for (i = 0; i < theMaxLength; i++)
- if (myptr[i] == 0x0d) // new line (Mac CR)?
- if (!foundStart)
- { /* still looking for start of the line */
- line_counter += 1;
- if (line_counter == line_to_go)
- {
- mySelStart = i + 1;
- foundStart = true;
- }
- }
- else
- { /* now we found the end of the line */
- mySelEnd = i + 1;
- break;
- }
-
- /* Beep if we found no start of line */
- if ((mySelStart < 0) && (line_to_go > 1))
- { /* Hmm, didn't find it! */
- mySelStart = theMaxLength;
- mySelEnd = theMaxLength;
- SysBeep(1);
- }
-
- /* if no end of line found, ASSUME it is last line of file */
- if (mySelEnd < mySelStart)
- mySelEnd = theMaxLength;
-
- /* Set up TE with selection */
- (**gSrcWind_TE32KH).selStart = mySelStart;
- (**gSrcWind_TE32KH).selEnd = mySelEnd;
-
- /* show them that we're not in Kansas anymore! */
- SetPort(gSrcWind_Window);
- InvalRect(&(gSrcWind_Window->portRect));
- ShowSelect();
- }
-
-
- // ==============================================
- // Search forward/backward from current start of selection, to match braces.
- // This is a quick hack, it currently does *not* handle skipping over braces in
- // comments or quoted strings, so beware.
- void MatchBracesAtCurSel(void)
- {
- int valence; // keep track of brace level
- long theMaxLength; // remember end index of buffer
- long begPos, endPos; // forward/backward search indexes
- char *textPtr; // simplified pointer to text buffer
-
- End_Make_Undoable();
- End_Make_Redoable();
-
- // find end of buffer
- theMaxLength = (**gSrcWind_TE32KH).teLength;
- // start out at the beginning of the selection
- begPos = (**gSrcWind_TE32KH).selStart;
- textPtr = (*(**gSrcWind_TE32KH).hText);
-
- // If we are sitting right before (on) a close brace, back up one so that
- // we don't immediately count it when scanning backwards.
- if ((textPtr[begPos] == '}') && (begPos>0))
- begPos--;
-
- // search backward for first open brace we find (almost). We have to
- // remember valence in case there's an intermediate { } to skip over.
- valence = 0;
- while ((begPos>=0) && (valence>=0))
- {
- if (textPtr[begPos] == '{')
- valence--; // back out a level
- else if (textPtr[begPos] == '}')
- valence++; // in a level
- if (valence>=0)
- begPos--; // keep going back...
- }
-
- // At this point we should have found a start brace, and the valence is -1.
- // If this is not true, we could search forward for the first open brace
- // and start from there instead, but that's not the best assumption, IMHO.
- // For this implementation, we simply decide it is an error & stop.
- if (valence < 0)
- {
- // begPos is ON the open brace... we want to start searching forward
- // one character AFTER this.
- endPos = begPos+1;
-
- // search forward for first close brace we find (almost). We have to
- // remember valence in case there's an intermediate { } to skip over.
- valence = 0;
- while ((endPos<theMaxLength) && (valence>=0))
- {
- if (textPtr[endPos] == '{')
- valence++; // in a level
- else if (textPtr[endPos] == '}')
- valence--; // back out level
- // increase ALWAYS, this lets us select end brace too
- endPos++; // keep going on...
- }
- }
-
- // OK, if we've gotten this far and valence is negative, we found both ends.
- // Otherwise no matches were found, and we beep!
- if (valence < 0)
- {
- // select what we found
- (**gSrcWind_TE32KH).selStart = begPos;
- (**gSrcWind_TE32KH).selEnd = endPos;
-
- // show selected area
- SetPort(gSrcWind_Window);
- InvalRect(&(gSrcWind_Window->portRect));
- ShowSelect();
- }
- else
- SysBeep(1);
-
- }
-
-
-
- // ==============================================
- void MyResizeWindow(WindowPtr w, short h, short v)
- {
- Rect oldHorizBar;
- Rect r;
-
- SetPort(w);
-
- oldHorizBar = w->portRect;
- oldHorizBar.top = oldHorizBar.bottom - (SBarWidth+1);
-
- SizeWindow(w, h, v, false);
-
- // remember this new size in prefs
- GetGlobalWindowRect(w, &(**gFilePrefs_h).srcWind_pos);
-
- InvalRect(&w->portRect);
-
- SetView(w);
-
- EraseRect(&oldHorizBar);
-
- MoveControl(gSrcWind_VScroll, w->portRect.right - SBarWidth, w->portRect.top-1);
- SizeControl(gSrcWind_VScroll, SBarWidth+1, w->portRect.bottom - w->portRect.top-(SBarWidth-2));
- r = (**gSrcWind_VScroll).contrlRect;
- ValidRect(&r);
-
- AdjustScrollBar();
- } // MyResizeWindow
-
-
-
- // ==============================================
- static void MyGrowWindow(WindowPtr w, Point p)
- {
- GrafPtr savePort;
- long theResult;
- Rect r;
-
- GetPort(&savePort);
- SetPort(w);
-
- GetMaxGrowRect(w, &r);
- theResult = GrowWindow(w, p, &r);
- if (theResult != 0)
- MyResizeWindow(w, LoWord(theResult), HiWord(theResult));
-
- SetPort(savePort);
- } // MyGrowWindow
-
-
-
- // ==============================================
- int CloseMyWindow(void)
- {
-
- if (gSrcWind_VRefNum != 0)
- {
- FilePrefs_Write(gSrcWind_VRefNum, gSrcWind_FileName); // Save window info
- // OK, now we're done with this file, release the pesky Working Directory
- // CloseWD(gSrcWind_VRefNum);
- }
-
- // if there's a window (always) then hide it
- if (gSrcWind_Window)
- HideWindow(gSrcWind_Window);
- gSrcWind_visible = false;
- ShowArrowCursor();
-
- // Image window also no longer valid!
- CloseImageWindow();
- gImageWindIsValid = false;
-
- // get rid of TE text (select all & delete)
- if (gSrcWind_TE32KH)
- {
- TE32KSetSelect(0, (**gSrcWind_TE32KH).teLength, gSrcWind_TE32KH);
- TE32KDelete(gSrcWind_TE32KH);
- }
-
- AdjustScrollBar();
-
- SetUpFiles();
-
- return 0; // should be void fn!?
- }
-
-
- // ==============================================
- int DoActivateEditor(Boolean becomingActive)
- {
- if (becomingActive)
- {
- TE32KActivate(gSrcWind_TE32KH);
- ShowControl(gSrcWind_VScroll);
- DrawGrowIcon(gSrcWind_Window);
- }
- else
- {
- TE32KDeactivate(gSrcWind_TE32KH);
- HideControl(gSrcWind_VScroll);
- /* the growbox should be changed immediately here */
- DrawGrowIcon(gSrcWind_Window);
- }
- return 0; // should be void fn!?
- }
-
- // ==============================================
- void Init_Editor(void)
- {
- CursHandle hCurs;
- TE32KInit();
- vScrollUPP = NewControlActionProc(ScrollProc);
- // Note: iBeamCursor & watchCursor are defined in ToolUtils.h
- hCurs = GetCursor(iBeamCursor);
- gEditCursor = **hCurs;
- gSrcWind_Window = NULL;
- SetUpFiles();
- PreInitWindows();
- }
-
-
- // ==============================================
- int DoEditMouseDown(int windowPart, WindowPtr whichWindow, EventRecord *myEvent)
- {
- switch (windowPart) {
- case inGoAway:
- if (ours(whichWindow) && (gDoingRender == 0))
- if (TrackGoAway(gSrcWind_Window, myEvent->where))
- DoFile(fmn_close);
- break;
-
- case inDrag:
- if (ours(whichWindow))
- {
- SelectWindow(whichWindow);
- DragWindow(whichWindow, myEvent->where, &gDragBounds);
- GetGlobalWindowRect(whichWindow, &(**gFilePrefs_h).srcWind_pos);
- }
- break;
-
- case inGrow:
- if (ours(whichWindow))
- MyGrowWindow(whichWindow, myEvent->where);
- break;
-
- case inZoomIn:
- case inZoomOut:
- SelectWindow(whichWindow);
- if (TrackBox(whichWindow, myEvent->where, windowPart))
- {
- EraseRect(&((WindowPtr)whichWindow)->portRect);
- ZoomWindow((WindowPtr)whichWindow, windowPart, (WindowPtr)whichWindow==FrontWindow());
- MyResizeWindow(whichWindow,
- whichWindow->portRect.right - whichWindow->portRect.left,
- whichWindow->portRect.bottom - whichWindow->portRect.top);
- }
- break;
-
- case inContent:
- if (whichWindow != FrontWindow())
- SelectWindow(whichWindow);
- else if (ours(whichWindow))
- DoContent(whichWindow, myEvent);
- break;
- }
- return 0; // should be void fn!?
- }
-
-
-
- // ==============================================
- void SrcWindMaintainCursor(void)
- {
- Point pt;
- WindowPeek wPtr;
- GrafPtr savePort;
- Rect shortRect;
- LongRect aLongRect;
-
- GetPort(&savePort);
-
- // update the cursor if over our window
- wPtr=(WindowPeek)FrontWindow();
- if ( ours((WindowPtr)wPtr) )
- {
- SetPort((GrafPtr)wPtr);
- // is cursor inside editor window?
- GetMouse(&pt);
- aLongRect = (**gSrcWind_TE32KH).viewRect;
- LongRectToRect(&aLongRect,&shortRect);
- if (PtInRect(pt, &shortRect))
- SetCursor(&gEditCursor);
- else
- ShowArrowCursor();
- }
- // let cursor blink
- if (gSrcWind_TE32KH)
- TE32KIdle(gSrcWind_TE32KH);
-
- SetPort(savePort);
- }
-
-
- static void SrcWindClickLoop(void)
- {
- SrcWindClickRoutine();
- }
-
-
- static void SrcWindClickRoutine(void)
- {
- short controlMax,controlMin,controlVal,lineHeight;
- LongRect aLongRect;
- Rect viewRect;
- Point mousePosShort;
- RgnHandle saveClip;
- long vDelta;
-
- aLongRect = (**gSrcWind_TE32KH).viewRect;
- LongRectToRect(&aLongRect,&viewRect);
- lineHeight = (**gSrcWind_TE32KH).lineHeight;
-
- vDelta = 0L;
-
- GetMouse(&mousePosShort);
-
- if (!PtInRect(mousePosShort,&viewRect))
- {
- controlMax = GetControlMaximum(gSrcWind_VScroll);
- controlMin = GetControlMinimum(gSrcWind_VScroll);
- controlVal = GetControlValue(gSrcWind_VScroll);
-
- if (mousePosShort.v>viewRect.bottom && controlVal<controlMax)
- {
- vDelta = -lineHeight;
- SetControlValue(gSrcWind_VScroll,controlVal+1);
- }
-
- else if (mousePosShort.v<viewRect.top && controlVal>controlMin)
- {
- vDelta = lineHeight;
- SetControlValue(gSrcWind_VScroll,controlVal-1);
- }
-
- }
-
- if (vDelta)
- {
- saveClip = NewRgn();
- GetClip(saveClip);
- ClipRect(&(gSrcWind_Window->portRect));
-
- TE32KScroll(0,vDelta,gSrcWind_TE32KH);
-
- SetClip(saveClip);
- DisposeRgn(saveClip);
- }
- }
-
- // ==============================================
- // UNDO / REDO interface functions
- // (called in Pov.c and UndoRedoSystem.c)
- // ==============================================
-
- // ==============================================
- // Undo function
- void SrcWindUndo(void)
- {
- if(My_DoUndo() == true)
- gSrcWind_dirty = true;
- // else
- // => error, can't undo
- ShowSelect(); // scroll to undone area
- }
-
- // ==============================================
- // Redo function
- void SrcWindRedo(void)
- {
- if(My_DoRedo() == true)
- gSrcWind_dirty = true;
- // else
- // => error, can't redo
-
- ShowSelect(); // scroll to redone area
- }
-